#include "PluginManager.h"
#include "ObjectManager.h"

PluginModule::PluginModule()
{
	Instance = NULL;
	memset(Name, 0, PLUGINNAMELEN);
}

PluginManager m_PluginManager;

PluginManager::PluginManager()
{
	moduleCount = 0;
	Disposing = false;
}

PluginManager::~PluginManager()
{
	Disposing = true;
	for(int i = 0 ; i < moduleCount; i++)
		modules[i].Instance->DeleteThis();
}

bool PluginManager::HandleCommand(Command &newCommand)
{
	if(Disposing)
		return false;

	bool IsGood = false;

	for(int i = 0; i < moduleCount; i++)
	{
		for(int j = 0; j < modules[i].Info.numOfCommands; j++)
		{
			if(newCommand.name == modules[i].Info.commands[j])
			{
				IsGood = modules[i].Instance->HandleCommand(newCommand);
				break;
			}
		}
		if(IsGood)
			break;
	}

	return IsGood;
}

void PluginManager::Initialize()
{
	for(int i = 0; i < moduleCount; i++)
		modules[i].Instance->Initialize(this, &m_ObjectManager);
}

void PluginManager::Dispose()
{
	for(int i = 0; i < moduleCount; i++)
		modules[i].Instance->Dispose();
}

bool PluginManager::Load(char *path)
{
	char olddir[MAX_PATH];
	char buffer[2048];
	
	GetCurrentDirectoryA(sizeof(olddir), olddir);
	GetCurrentDirectoryA(sizeof(buffer), buffer);
	strcat_s(buffer, 2048, "\\plugins");
	SetCurrentDirectoryA(buffer);
	strcat_s(buffer, 2048, "\\");
	strcat_s(buffer, 2048, path);
	HMODULE TempModule = LoadLibraryA(buffer);
	if(TempModule == NULL)
	{
		SetCurrentDirectoryA(olddir);
		std::cout << "Failed to load " << path << "." << std::endl;
		return false;
	}
	GetPluginInterfaceFunc Func= (GetPluginInterfaceFunc)GetProcAddress(TempModule, "GetInterfaceVersion");
	int Value = 0;
	if(Func)
		Value = Func();
	if(Value < 0x01000000)
	{
		SetCurrentDirectoryA(olddir);
		std::cout << path << " Did not export the GetInterfaceVersion function correctly." << std::endl;
		return false;
	}
	modules[moduleCount].module = TempModule;
	modules[moduleCount].newInstance = (CreateInstanceFunc)GetProcAddress(TempModule,"CreateInstance");
	modules[moduleCount].Instance = modules[moduleCount].newInstance();
	modules[moduleCount].Instance->Initialize(this, &m_ObjectManager);
	modules[moduleCount].Info = modules[moduleCount].Instance->GetModuleInfo();
	moduleCount++;
	SetCurrentDirectoryA(olddir);
	std::cout << "Loaded Plugin: " << path << std::endl;
	std::cout << "Author: " << modules[moduleCount-1].Info.author << std::endl;
	std::cout << "Has " << modules[moduleCount-1].Info.numOfCommands << " commands." << std::endl;
	return true;
}

bool PluginManager::Unload(char *path)
{
	return false;
}

void PluginManager::UnloadAll()
{
}

void PluginManager::Toggle(char *path)
{
}

int __stdcall PluginManager::GetVersion()
{
	int Return = 0x00010000;
	return Return;
}